package com.gitee.huanminabc.fastboot.orm;

import com.gitee.huanminabc.jcommon.container.DataPage;
import com.gitee.huanminabc.fastboot.orm.exception.ORMException;
import com.gitee.huanminabc.fastboot.orm.base.BaseMapper;
import com.gitee.huanminabc.fastboot.orm.base.BaseMethodStatement;
import com.gitee.huanminabc.fastboot.orm.proxy.OrmByteBuddyProxy;
import com.gitee.huanminabc.fastboot.proxy.ByteBuddyProxy;
import com.gitee.huanminabc.jlambda_sql.warapper.LambdaDeleteWrapper;
import com.gitee.huanminabc.jlambda_sql.warapper.LambdaQueryWrapper;
import com.gitee.huanminabc.jlambda_sql.warapper.LambdaUpdateWrapper;
import com.gitee.huanminabc.jlambda_sql.warapper.LambdaWrapper;
import com.gitee.huanminabc.nullchain.Null;
import com.gitee.huanminabc.nullchain.NullExt;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 简要描述
 *
 * @Author: huanmin
 * @Date: 2025/4/5 16:42
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
public abstract class AbstractMapperManager<T extends NullExt<T>> implements BaseMethodStatement<T> {

    private final Class<T> entityClass;
    private static final BaseMapper mapper = OrmByteBuddyProxy.createProxyBaseMapperMethod();

    public AbstractMapperManager() {
        entityClass = getEntityClass();
    }

    //获取LambdaQueryWrapper
    public LambdaQueryWrapper<T> createQueryWrapper() {
        return LambdaQueryWrapper.create(entityClass);
    }

    public LambdaQueryWrapper<T> createQueryWrapper(String alias) {
        return LambdaQueryWrapper.create(entityClass, alias);
    }

    public LambdaUpdateWrapper<T> createUpdateWrapper() {
        return LambdaUpdateWrapper.create(entityClass);
    }

    public LambdaUpdateWrapper<T> createUpdateWrapper(T entity) {
        return LambdaUpdateWrapper.create(entity);
    }

    public LambdaDeleteWrapper<T> createDeleteWrapper() {
        return LambdaDeleteWrapper.create(entityClass);
    }
    public LambdaWrapper<T> createWrapper() {
        return  LambdaWrapper.create(entityClass);
    }
    public LambdaWrapper<T> createWrapper(String alias) {
        return  LambdaWrapper.create(entityClass,alias);
    }


    public List<T> selectList(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.selectList(entityClass, queryWrapper);
    }

    @Override
    public boolean insert(T entity) {
        if (entity == null) {
            throw new ORMException("entity is null");
        }
        return mapper.insert(entity);
    }

    @Override
    public boolean insertBatch(List<T> entityList) {
        if (entityList == null) {
            throw new ORMException("entityList is null");
        }
        if (entityList.isEmpty()) {
            return false;
        }
        return mapper.insertBatch(entityList);
    }

    @Override
    public boolean insertOrUpdate(T entity) {
         if (entity == null) {
             throw new ORMException("entity is null");
         }
         return mapper.insertOrUpdate(entity);
    }

    @Override
    public boolean deleteById(Serializable id) {
        if (id == null) {
            throw new ORMException("id is null");
        }
        return mapper.deleteById(entityClass, id);
    }

    @Override
    public boolean delete(LambdaDeleteWrapper<T> deleteWrapper) {
        if (deleteWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.delete(deleteWrapper);
    }

    @Override
    public boolean deleteByIds(Collection<?> idList) {
        if (idList == null) {
            throw new ORMException("idList is null");
        }
        return mapper.deleteByIds(entityClass, idList);
    }

    @Override
    public boolean updateById(T entity) {
        if (entity == null) {
            throw new ORMException("entity is null");
        }
        return mapper.updateById(entity);
    }

    @Override
    public boolean update(LambdaUpdateWrapper<T> updateWrapper) {
        if (updateWrapper == null) {
            throw new ORMException("updateWrapper is null");
        }
        return mapper.update(updateWrapper);
    }

    @Override
    public T selectById(Serializable id) {
        if (id == null) {
            throw new ORMException("id is null");
        }
        T t = mapper.selectById(entityClass, id);
        return Null.orEmpty(t, entityClass);
    }

    @Override
    public List<T> selectByIds(Collection<? extends Serializable> idList) {
        if (idList == null) {
            throw new ORMException("idList is null");
        }
        return mapper.selectByIds(entityClass, idList);
    }

    @Override
    public T selectOne(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        T t = mapper.selectOne(entityClass, queryWrapper);
        return Null.orEmpty(t, entityClass);
    }

    @Override
    public boolean exists(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.exists(queryWrapper);
    }

    @Override
    public long selectCount(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.selectCount(queryWrapper);
    }

    @Override
    public Map<String, Object> selectMap(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.selectMap(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> selectMaps(LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        return mapper.selectMaps(queryWrapper);
    }

    @Override
    public <P extends DataPage<T>> P selectPage(int page, int pageSize, LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        if (page < 1) {
            page = 1;
        }
        if (pageSize < 1) {
            pageSize = 10;
        }
        return mapper.selectPage(entityClass, page, pageSize, queryWrapper);
    }

    @Override
    public <P extends DataPage<Map<String, Object>>> P selectMapsPage(int page, int pageSize, LambdaQueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            throw new ORMException("queryWrapper is null");
        }
        if (page < 1) {
            page = 1;
        }
        if (pageSize < 1) {
            pageSize = 10;
        }
        return mapper.selectMapsPage(page, pageSize, queryWrapper);
    }

    private Class<T> getEntityClass() {
        final Class<?> entityClassGen;
        try {
            entityClassGen = ByteBuddyProxy.getProxClassGenericType(getClass(), 0);
            if (entityClassGen != null) {
                return (Class<T>) entityClassGen;
            } else {
                throw new ORMException("Unable to determine base mapper class");
            }
        } catch (Exception e) {
            throw new ORMException("Failed to get generic type", e);
        }
    }

    @Override
    public T selectOne(LambdaWrapper<T> queryWrapper) {
         return  mapper.selectOne(entityClass, queryWrapper);
    }

    @Override
    public List<T> selectList(LambdaWrapper<T> queryWrapper) {
        return mapper.selectList(entityClass, queryWrapper);
    }

    @Override
    public Map<String, Object> selectMap(LambdaWrapper<T> queryWrapper) {
        return mapper.selectMap(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> selectMaps(LambdaWrapper<T> queryWrapper) {
        return  mapper.selectMaps(queryWrapper);
    }

    @Override
    public <P extends DataPage<T>> P selectPage(int page, int pageSize, LambdaWrapper<T> queryWrapper) {
        return  mapper.selectPage(entityClass, page, pageSize, queryWrapper);
    }

    @Override
    public <P extends DataPage<Map<String, Object>>> P selectMapsPage(int page, int pageSize, LambdaWrapper<T> queryWrapper) {
        return  mapper.selectMapsPage(page, pageSize, queryWrapper);
    }

    @Override
    public boolean exists(LambdaWrapper<T> queryWrapper) {
        return   mapper.exists(queryWrapper);
    }

    @Override
    public long selectCount(LambdaWrapper<T> queryWrapper) {
        return mapper.selectCount(queryWrapper);
    }

    @Override
    public boolean update(LambdaWrapper<T> updateWrapper) {
        return mapper.update(updateWrapper);
    }

    @Override
    public boolean delete(LambdaWrapper<T> deleteWrapper) {
        return mapper.delete(deleteWrapper);
    }
}
